package cn.edu.klmy.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import web.models.BatchSaveResult;
import web.models.CommonResult;
import web.models.Page;
import web.util.DaoUtil.SqlOperator;
import web.util.ExcelReader;
import cn.edu.klmy.controller.importdata.ExcelMapperStudent;
import cn.edu.klmy.controller.importdata.ImportError;
import cn.edu.klmy.dao.IAccountDao;
import cn.edu.klmy.dao.IAuthorityDao;
import cn.edu.klmy.dao.IStudentClaszRelDao;
import cn.edu.klmy.dao.IStudentDao;
import cn.edu.klmy.models.student.Student;
import cn.edu.klmy.models.user.UserType;

@Controller
@RequestMapping("/student")
public class StudentController {
       // 如果使用了自定义的类型，或者enum，进行了数据类型的转换，需要在这里注册，然后方可以使用
//    @InitBinder
//    protected void initBinder(HttpServletRequest request,
//                              ServletRequestDataBinder binder) throws Exception {
//        binder.registerCustomEditor(Sex.class, new SexTypeEnumEditor());
//        binder.registerCustomEditor(Nation.class, new NationTypeEnumEditor());
//    }

    @Resource(name = "studentDao")
    private IStudentDao studentDao;

    @Resource(name = "authorityDao")
    private IAuthorityDao authorityDao;

    @Resource(name = "accountDao")
    private IAccountDao accountDao;

    @Resource(name = "studentClaszRelDao")
    private IStudentClaszRelDao studentClaszRelDao;

    @RequestMapping("/add")
    @ResponseBody
    public CommonResult addStudent(@ModelAttribute Student student) {
    	//增加学生
        studentDao.addStudent(student);
        //增加登录账户
        accountDao.addAccount(student.getIdentityCardNumber(), student.getName(), UserType.Student.getMark());
        //增加登录学生的默认权限
        //int userId = accountDao.getAccountId(student.getIdentityCardNumber());
        //authorityDao.addDefaultPermission(userId);
        return new CommonResult(new Boolean(true));
    }

//    @RequestMapping("/add-and-inclasz")
//    @ResponseBody
//    public CommonResult addStudentAndInClasz(@ModelAttribute Student student, @RequestParam int claszId) {
//        studentDao.addStudent(student);
//        accountDao.addAccount(student.getIdentityCardNumber(), student.getName(), UserType.Student.getMark());
//        studentClaszRelDao.addStudentsToClasz(new int[]{student.getId()}, claszId, );
//        return new CommonResult(new Boolean(true));
//    }

    @RequestMapping("/update")
    @ResponseBody
    public CommonResult updateStudent(@ModelAttribute Student student) {
    	// 考虑更新身份证号号的问题
    	Student oldStudent = studentDao.getStudent("id", student.getId());
    	if (!oldStudent.getIdentityCardNumber().equals(student.getIdentityCardNumber())) {
    		accountDao.changeAccountIdentityCardNumber(oldStudent.getIdentityCardNumber(), student.getIdentityCardNumber());
    	}
        if(student.getExecutiveClass() == null || student.getExecutiveClass()==0)
            student.setExecutiveClass(null);
        if(student.getTeachingClass() == null || student.getTeachingClass()==0)
            student.setTeachingClass(null);
        studentDao.updateStudent(student);
        return new CommonResult(new Boolean(true));
    }

    @RequestMapping("/remove")
    @ResponseBody
    public CommonResult removeStudent(@RequestParam int studentId) {
        Student student = studentDao.getStudent("id", studentId);
        if (student != null) {
        	//删除权限
            //int userId = accountDao.getAccountId(student.getIdentityCardNumber());
            //authorityDao.removeUserPermissions(userId);
            //删除登录账户
            accountDao.removeAccount(student.getIdentityCardNumber());
            //删除班级中的学生关联
            //studentClaszRelDao.removeStudentFromAllClasz(student.getId());
            //删除学生的定课信息，可以在DAO层实现
            //删除学生
            studentDao.removeStudent(studentId);
        }
        return new CommonResult(new Boolean(true));
    }

    @RequestMapping("/{studentId}")
    @ResponseBody
    public Student getStudent(@RequestParam int studentId) {
        return studentDao.getStudent("id", studentId);
    }

    @RequestMapping("/idno/{identityCardNumber}")
    @ResponseBody
    public Student getStudentByIdNo(@PathVariable String identityCardNumber) {
        return studentDao.getStudent("student_id_no", "'" + identityCardNumber + "'");
    }

    @RequestMapping("/exists")
    @ResponseBody
    public CommonResult studentExists(@RequestParam String identityCardNumber) {
    	boolean result = studentDao.studentExistsByIdentityCardNumber(identityCardNumber);
    	return new CommonResult(new Boolean(result));
    }

    @RequestMapping("/all")
    @ResponseBody
    public Page<Student> getStudentsPage(@RequestParam int page, @RequestParam int rows) {
        List<Student> students = studentDao.getStudents(null, page, rows);
        int count = studentDao.getStudentCount(null);
        return new Page<Student>(count, students);
    }

    @RequestMapping("/search-by-adminclass")
    @ResponseBody
    public Page<Student> getStudentsPageByAdminClass(@RequestParam String adminClass, @RequestParam int page, @RequestParam int rows) {
    	return getStudentsByEqualsFilter("admin_class_id", Integer.parseInt(adminClass), page, rows);
    }

    @RequestMapping("/search-by-studyclass")
    @ResponseBody
    public Page<Student> getStudentsPageByStudyClass(@RequestParam String studyClass, @RequestParam int page, @RequestParam int rows) {
    	return getStudentsByEqualsFilter("study_class_id", Integer.parseInt(studyClass), page, rows);
    }

    @RequestMapping("/search-not-in-studyClass")
    @ResponseBody
    public Page<Student> getStudentsPageNotInStudyClass(@RequestParam int page, @RequestParam int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put("study_class_id", new Object[]{ SqlOperator.isNull, null });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
        return new Page<Student>(count, students);
    }

    @RequestMapping("/search-not-in-studyClass-byname")
    @ResponseBody
    public Page<Student> getStudentsPageNotInStudyClassSearchByName(@RequestParam String name, @RequestParam int page, @RequestParam int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put("study_class_id", new Object[]{ SqlOperator.isNull, null });
		params.put("STUDENT_NAME", new Object[]{ SqlOperator.like, name });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
        return new Page<Student>(count, students);
    }

    @RequestMapping("/search-not-in-adminClass")
    @ResponseBody
    public Page<Student> getStudentsPageNotInAdminClass( @RequestParam int page, @RequestParam int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put("admin_class_id", new Object[]{ SqlOperator.isNull, null });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
        return new Page<Student>(count, students);
    }

    @RequestMapping("/search-not-in-adminClass-byname")
    @ResponseBody
    public Page<Student> getStudentsPageNotInAdminClassSearchByName(@RequestParam String name, @RequestParam int page, @RequestParam int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put("admin_class_id", new Object[]{ SqlOperator.isNull, null });
		params.put("STUDENT_NAME", new Object[]{ SqlOperator.like, name });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
        return new Page<Student>(count, students);
    }

    @RequestMapping(value = "/exportStudents", method = RequestMethod.POST)
    @ResponseBody
    public BatchSaveResult<String> handleFormUpload(@RequestParam(value = "file") MultipartFile file) throws Exception {
        String fileName = null;
        if (!file.isEmpty()) {
            fileName = file.getOriginalFilename();
            ExcelMapperStudent ems = new ExcelMapperStudent();
            List students = ExcelReader.readExcel(file.getInputStream(), ems, fileName.toUpperCase().endsWith(".XLSX"));
            if (null != students && !students.isEmpty()) {
                BatchSaveResult<String> bsr = new BatchSaveResult<String>();
                bsr.setRecordCount(students.size());
                int sucessCount = 0;
                List<String> identityCardNumbers = new ArrayList<String>();
                List<String> validErrors = new ArrayList<String>();
                for (Object student : students) {
                	if (student == null) 
                		continue;
                    try {
                        addStudent((Student) student);
                    } catch (Throwable t) {
                    	String e = "身份证号:[" + ((Student) student).getIdentityCardNumber() + "]";
                    	if (!identityCardNumbers.contains(e)) {
                    		identityCardNumbers.add(e);
                    	}
                        continue;
                    }
                    sucessCount++;
                }
                if (ems.getImportErrors() != null && !ems.getImportErrors().isEmpty()) {
                	for (ImportError e : ems.getImportErrors()) {
                		if (e.getType() == 0) {
                			validErrors.add("所在行:[" + (e.getRow().getRowNum() + 1) + "] 信息:[" + e.getError() + "]");
                		} else {
                			validErrors.add("所在行:[" + (e.getRow().getRowNum() + 1) + "] 信息:[" + e.getError() + "]");
                		}
                	}
                }
                bsr.setSucessCount(sucessCount);
                bsr.setFailInfo(identityCardNumbers);
                bsr.setValidInfo(validErrors);
                return bsr;
            }
        }
        return null;
    }

    @RequestMapping(value = "/student-by-name", method = RequestMethod.POST)
    @ResponseBody
    public Page<Student> getStudentsPage(@RequestParam String name, @RequestParam int page, @RequestParam int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put("student_name", new Object[]{ SqlOperator.like, name });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
		return new Page<Student>(count, students);
    }

    private Page<Student> getStudentsByEqualsFilter(String colName, Object colVal, int page, int rows) {
		Map<String, Object[]> params = new HashMap<String, Object[]>();
		params.put(colName, new Object[]{ SqlOperator.equals, colVal });
		List<Student> students = studentDao.getStudents(params, page, rows);
		int count = studentDao.getStudentCount(params);
        return new Page<Student>(count, students);
    }

    public void setStudentDao(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void setStudentClaszRelDao(IStudentClaszRelDao studentClaszRelDao) {
        this.studentClaszRelDao = studentClaszRelDao;
    }
}
